/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wiiscript;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import parser.ChangeVariableListener;
import parser.PIELexer;
import parser.ParseException;
import parser.ParserInterface;
import parser.TokenMgrError;
import parser.VarEvent;
import systemInterface.Interface;
import wiiremotej.WiiRemote;
import wiiremotej.event.WRButtonEvent;

/**
 *
 * @author Evan
 */

public class Main {
    public enum OS {Mac, Windows, Linux, Unknown};
    private static String system;
    private static Frame frame;
    private ParserInterface parserInterface;
    private Interface systemInterface;
    private Run run = new Run();
    private WiiRemote remote;

    public WiiRemote getRemote() {
        return remote;
    }

    public void setRemote(WiiRemote remote) {
        this.remote = remote;
        remote.addWiiRemoteListener(new WiiRemoteListener());
    }
     public static void main(String[] args) {
        System.out.println(System.getProperty("os.name"));

        String laf = UIManager.getSystemLookAndFeelClassName();

        if(Main.getOS() == Main.OS.Mac) {
            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "WiiScript");
        }
        try {
            UIManager.setLookAndFeel(laf);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        Main main = new Main();
        main.init();
    }
    private void init() {
        if(Main.getOS() == Main.OS.Mac) {
            System.load(ClassLoader.getSystemResource("systemInterface/macInterface.so").getPath());
        } else if (Main.getOS() == Main.OS.Windows) {
            System.load(ClassLoader.getSystemResource("systemInterface/winInterface.dll").getPath());
        } else if (Main.getOS() == Main.OS.Linux) {
            System.load(ClassLoader.getSystemResource("systemInterface/linuxInterface.so").getPath());
        }
        Properties.init();

        systemInterface = new Interface();

        frame = new Frame(this);
        frame.setVisible(true);
        parserInterface = new ParserInterface(this);
        parserInterface.addChangeVariableListener(new ParserListener());
    }
    public void run(String text) {
        PIELexer.init(text, parserInterface);
        try {
            PIELexer.read();
            parserInterface.printTree();
        } catch (ParseException ex) {
            displayError(ex.getMessage());
        } catch (TokenMgrError ex) {
            displayError(ex.getMessage());
        }
        new Thread(run).start();
        
    }
    public void stop() {
        run.stop();
        parserInterface.resetVariables();
        parserInterface.clearTree();
    }
    public void setDebug(String text) {
        frame.setDebug(text);
    }
    public static OS getOS() {
        if(system == null) {
            system = System.getProperty("os.name").toLowerCase();
        }
        if(system.contains("mac")) {
            return OS.Mac;
        } else if(system.contains("windows")) {
            return OS.Windows;
        } else if(system.contains("linux")) {
            return OS.Linux;
        } else {
            return OS.Unknown;
        }
    }
    public static void displayError(String error) {
        frame.setError(error);
        System.out.println(error);
    }
    private class Run implements Runnable {
        private boolean running = true;
        @Override
        public void run() {
            while(running) {
                parserInterface.parse();
            }
            running = true;
        }
        public void stop() {
            running = false;
            parserInterface.resetVariables();
        }
    }
    private class ParserListener implements ChangeVariableListener {
        @Override
        public void variableChanged(VarEvent e) {
            if(e.getName().contains("keyboard")) {
                if((Boolean)e.getValue()) {
                    String key = e.getName().split("\\.")[1];
                    systemInterface.keyDown(Interface.getKeyCode(key));
                } else {
                    String key = e.getName().split("\\.")[1];
                    systemInterface.keyUp(Interface.getKeyCode(key));
                }
            }
        }
    }
    private class WiiRemoteListener extends WiiRemoteAdapter {
        @Override
        public void buttonInputReceived(WRButtonEvent evt) {
            if(evt.wasPressed(WRButtonEvent.A)) {
                buttonDown("a");
            }
            if(evt.wasPressed(WRButtonEvent.B)) {
                buttonDown("b");
            }
            if(evt.wasPressed(WRButtonEvent.DOWN)) {
                buttonDown("down");
            }
            if(evt.wasPressed(WRButtonEvent.HOME)) {
                buttonDown("home");
            }
            if(evt.wasPressed(WRButtonEvent.LEFT)) {
                buttonDown("left");
            }
            if(evt.wasPressed(WRButtonEvent.MINUS)) {
                buttonDown("minus");
            }
            if(evt.wasPressed(WRButtonEvent.ONE)) {
                buttonDown("one");
            }
            if(evt.wasPressed(WRButtonEvent.PLUS)) {
                buttonDown("plus");
            }
            if(evt.wasPressed(WRButtonEvent.RIGHT)) {
                buttonDown("right");
            }
            if(evt.wasPressed(WRButtonEvent.TWO)) {
                buttonDown("two");
            }
            if(evt.wasPressed(WRButtonEvent.UP)) {
                buttonDown("up");
            }

            if(evt.wasReleased(WRButtonEvent.A)) {
                buttonUp("a");
            }
            if(evt.wasReleased(WRButtonEvent.B)) {
                buttonUp("b");
            }
            if(evt.wasReleased(WRButtonEvent.DOWN)) {
                buttonUp("down");
            }
            if(evt.wasReleased(WRButtonEvent.HOME)) {
                buttonUp("home");
            }
            if(evt.wasReleased(WRButtonEvent.LEFT)) {
                buttonUp("left");
            }
            if(evt.wasReleased(WRButtonEvent.MINUS)) {
                buttonUp("minus");
            }
            if(evt.wasReleased(WRButtonEvent.ONE)) {
                buttonUp("one");
            }
            if(evt.wasReleased(WRButtonEvent.PLUS)) {
                buttonUp("plus");
            }
            if(evt.wasReleased(WRButtonEvent.RIGHT)) {
                buttonUp("right");
            }
            if(evt.wasReleased(WRButtonEvent.TWO)) {
                buttonUp("two");
            }
            if(evt.wasReleased(WRButtonEvent.UP)) {
                buttonUp("up");
            }
        }
        private void buttonDown(String button) {
            parserInterface.putVariable("wiiremote." + button, true);
        }
        private void buttonUp(String button) {
            parserInterface.putVariable("wiiremote." + button, false);
        }
    }
}
